package com.kdtech.rpc;

import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ProtocolConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.alibaba.dubbo.config.ServiceConfig;

/**
 * 远程调用服务端
 * 使用方法:
 * 	new RPCServer(xxx,xxx...).start()
 *
 * 停止服务：
 *  server.stop();
 *
 *
 *
 * @author KK
 *
 * @param <T>
 */
public class RPCServer<T> {
	private T impleObj;
	private int portNo;
	private String serviceName;
	private int threadCount = 500;
	private int timeout = 15000;//超时默认1秒
	private ServiceConfig<T> service;


	/**
	 * @param interfaceClass	接口class
	 * @param impleObj	服务的实例化对象
	 * @param portNo	端口
	 * @param serviceName	服务名称
	 */
	public RPCServer(T impleObj,int portNo, String serviceName) {
		super();
		this.impleObj=impleObj;
		this.portNo = portNo;
		this.serviceName = serviceName;
	}

	/**
	 * 开启服务
	 *
	 * 注意：
	 *    此方法执行后不会阻塞线程，执行完后会立即结束，在后台运行。
	 * @throws Exception
	 */
	public void start() throws Exception{
		// 当前应用配置
		ApplicationConfig application = new ApplicationConfig();
		application.setName(serviceName);

		// 连接注册中心配置
		RegistryConfig registry = new RegistryConfig();
		registry.setAddress("N/A");
//				registry.setAddress("10.20.130.230:9090");

		// 服务提供者协议配置
		ProtocolConfig protocol = new ProtocolConfig();
		protocol.setName("dubbo");
		protocol.setPort(portNo);
		protocol.setThreads(threadCount);
		protocol.setBuffer(1024*1024*5);

		// 注意：ServiceConfig为重对象，内部封装了与注册中心的连接，以及开启服务端口

		service = new ServiceConfig<T>();
		service.setApplication(application);
		service.setRegistry(registry); // 多个注册中心可以用setRegistries()
		service.setProtocol(protocol); // 多个协议可以用setProtocols()
		Class<?>[] interfaces =impleObj.getClass().getInterfaces();
		service.setInterface(interfaces[0]);
		service.setRef(impleObj);
		service.setRetries(0);
		service.setTimeout(timeout);

		// 暴露及注册服务
		service.export();
	}

	/**
	 * 停止服务
	 */
	public void stop() {
		service.unexport();
	}

	public int getPortNo() {
		return portNo;
	}

	public void setPortNo(int portNo) {
		this.portNo = portNo;
	}

	public String getServiceName() {
		return serviceName;
	}

	public void setServiceName(String serviceName) {
		this.serviceName = serviceName;
	}

	public int getThreadCount() {
		return threadCount;
	}

	public void setThreadCount(int threadCount) {
		this.threadCount = threadCount;
	}

	public int getTimeout() {
		return timeout;
	}

	public void setTimeout(int timeout) {
		this.timeout = timeout;
	}

	public ServiceConfig<T> getService() {
		return service;
	}

	public void setService(ServiceConfig<T> service) {
		this.service = service;
	}
}
